#include <iostream>
#include <typeinfo>
#include <cassert>
#include <unistd.h>
#include <any>

class Any
{
private:
    class holder
    {
    public:
        virtual ~holder() = default;
        virtual const std::type_info &type() noexcept = 0;
        virtual holder *clone() = 0;
    };
    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T &val)
            : _val(val)
        {
        }

        // 获取子类对象保存的数据类型
        virtual const std::type_info &type() noexcept
        {
            return typeid(T);
        }
        // 针对当前的对象自身，克隆出一个新的子类对象
        virtual holder *clone()
        {
            return new placeholder(_val);
        }

    public:
        T _val;
    };
    holder *_content = nullptr;

public:
    Any() = default;

    template <class T>
    Any(const T &val)
        : _content(new placeholder<T>(val))
    {
    }

    Any(const Any &other)
        : _content(other._content ? other._content->clone() : NULL)
    {
    }

    template <class T>
    Any &operator=(const T &val)
    {
        Any(val).swap(*this);
        return *this;
    }

    Any &operator=(const Any &other)
    {
        if (this != &other)
        {
            Any(other).swap(*this);
        }
        return *this;
    }

    ~Any()
    {
        delete _content;
    }

    // 返回子类对象保存的数据的指针
    template <typename T>
    T *get()
    {
        if (typeid(T) != _content->type())
            throw std::bad_cast();
        return &((placeholder<T> *)_content)->_val;
    }

    template <typename T>
    const T *get() const
    {
        if (typeid(T) != _content->type())
            throw std::bad_cast();
        return &((const placeholder<T> *)_content)->_val;
    }

    bool has_value() const
    {
        return _content != nullptr;
    }
    const std::type_info &type() const
    {
        if (!_content)
            throw std::bad_cast();
        return _content->type();
    }
    Any &swap(Any &other)
    {
        std::swap(_content, other._content);
        return *this;
    }
};

class Test
{
public:
    Test() { std::cout << "Test构造" << std::endl; }
    Test(const Test &t) { std::cout << "Test拷贝" << std::endl; }
    ~Test() { std::cout << "Test析构" << std::endl; }
};
int main()
{
    // std::any a;
    // a = 10;
    // int *pi = std::any_cast<int>(&a);
    // std::cout << *pi << std::endl;

    // a = std::string("hello");
    // std::string *ps = std::any_cast<std::string>(&a);
    // std::cout << *ps << std::endl;

    Any a;
    {
        Test t;
        a = t;
    }

    a = 10;
    int *pa = a.get<int>();
    std::cout << *pa << std::endl;
    a = std::string("nihao");
    std::string *ps = a.get<std::string>();
    std::cout << *ps << std::endl;

    return 0;
}